<div id="app"></div>
<script>
    const createAppAPI = (render) => {
        return function (rootComponent) {
            //app实例，内部有use，mount等方法
            const app = {
                mount(container) {
                    const vnode = {
                        tag: 'h2',
                        props: {
                            class: 'title'
                        },
                        children: rootComponent.data().foo
                    }
                    render(vnode, container)
                }
            }
            return app
        }
    }
    
    //根据渲染方法，定义render等函数  内部判断vnode的tag，分别渲染
    const createRenderer = (options) => {
        //定义渲染方法，最终被传入mount里面被调用
        const render = (vnode, container) => {
            //将vnode追加到container
            const parent = options.querySelector(container)
            const child = options.createElement(vnode.tag)
            if (typeof vnode.children === "string") {
                child.textContent = vnode.children
            }
            options.insert(child, parent)
        }
        return {
            render,
            createApp: createAppAPI(render)
        }
    }

    //自定义渲染器，传入方法
    const renderer = createRenderer({
        querySelector(sel) {
            return document.querySelector(sel)
        },
        createElement(tag) {
            return document.createElement(tag)
        },
        insert(child, parent) {
            parent.appendChild(child)
        }
    })

    //渲染器创建app，app调用mount方法挂载
    renderer.createApp({
        data() {
            return {
                foo: 'Hello!!'
            }
        }
    }).mount("#app")
    // console.log(renderer)
</script>